package com.zxtech.zzm.zxmonitorsocket.thread

import java.util.concurrent.Executors
import java.util.concurrent.LinkedBlockingQueue
import java.util.concurrent.ThreadPoolExecutor
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy
import java.util.concurrent.TimeUnit.SECONDS

/**
 * 线程池管理 管理整个项目中所有的线程，所以不能有多个实例对象
 */
class ThreadPoolManager private constructor() {
  private val corePoolSize: Int//核心线程池的数量，同时能够执行的线程数量
  private val maximumPoolSize: Int//最大线程池数量，表示当缓冲队列满的时候能继续容纳的等待任务的数量
  private val executor: ThreadPoolExecutor
  private val keepAliveTime: Long = 60 //存活时间 60秒
  private val unit = SECONDS

  /**
   * 执行任务
   */
  fun execute(runnable: Runnable?) {
    if (runnable == null) return
    executor.execute(runnable)
  }

  /**
   * 从线程池中移除任务
   */
  fun remove(runnable: Runnable?) {
    if (runnable == null) return
    executor.remove(runnable)
  }

  fun destory() {
    executor.shutdownNow()
  }

  companion object {
    /**
     * 单例设计模式（饿汉式）
     * 单例首先私有化构造方法，然后饿汉式一开始就开始创建，并提供get方法
     */
    private var mInstance: ThreadPoolManager? = ThreadPoolManager()
    val instance: ThreadPoolManager?
      get() {
        if (mInstance == null) {
          mInstance = ThreadPoolManager()
        }
        return mInstance
      }
  }

  init {
    /**
     * 给corePoolSize赋值：当前设备可用处理器核心数*2 + 1
     */
    corePoolSize = Runtime.getRuntime()
        .availableProcessors() * 2 + 1
    maximumPoolSize = corePoolSize * 2 //虽然maximumPoolSize用不到，但是需要赋值，否则报错
    executor = ThreadPoolExecutor(
        corePoolSize,  //当某个核心任务执行完毕，会依次从缓冲队列中取出等待任务
        maximumPoolSize,  //5,先corePoolSize,然后new LinkedBlockingQueue<Runnable>(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
        keepAliveTime,  //表示的是maximumPoolSize当中等待任务的存活时间
        unit,
        LinkedBlockingQueue(),  //缓冲队列，用于存放等待任务，Linked的先进先出
        Executors.defaultThreadFactory(),  //创建线程的工厂
        AbortPolicy() //用来对超出maximumPoolSize的任务的处理策略
    )
  }
}